﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.Serialization;
using System.Xml.Serialization;

namespace Kyoh.Lib.Component.Traces
{
    [Serializable]
    [XmlSchemaProviderAttribute("GetTypedTableSchema")]
    internal class TraceDataTable : DataTable, IEnumerable, IEnumerable<TraceData>
    {
        private DataColumn columnIndex;
        private DataColumn columnId;
        private DataColumn columnEventType;
        private DataColumn columnMessage;
        private DataColumn columnDetail;
        private DataColumn columnDateTime;
        private DataColumn columnTimestamp;
        private DataColumn columnProcessId;
        private DataColumn columnThreadId;
        private DataColumn columnSource;
        private DataColumn columnCallstack;
        private DataColumn columnRelatedActivityId;
        private DataColumn columnLogicalOperations;

        public TraceDataTable()
        {
            this.TableName = "TraceData";
            this.BeginInit();
            this.InitClass();
            this.EndInit();
        }

        protected TraceDataTable(SerializationInfo info, StreamingContext context) :
            base(info, context)
        {
            this.InitVars();
        }

        protected override DataTable CreateInstance()
        {
            return new TraceDataTable();
        }

        private void InitVars()
        {
            this.columnIndex = base.Columns["Index"];
            this.columnId = base.Columns["Id"];
            this.columnEventType = base.Columns["EventType"];
            this.columnMessage = base.Columns["Message"];
            this.columnDetail = base.Columns["Detail"];
            this.columnDateTime = base.Columns["DateTime"];
            this.columnTimestamp = base.Columns["Timestamp"];
            this.columnProcessId = base.Columns["ProcessId"];
            this.columnThreadId = base.Columns["ThreadId"];
            this.columnSource = base.Columns["Source"];
            this.columnCallstack = base.Columns["Callstack"];
            this.columnRelatedActivityId = base.Columns["RelatedActivityId"];
            this.columnLogicalOperations = base.Columns["LogicalOperations"];
        }

        private void InitClass()
        {
            this.columnIndex = new DataColumn("Index", typeof(int), null, MappingType.Element);
            base.Columns.Add(this.columnIndex);
            this.columnIndex.AutoIncrementSeed = 1;
            this.columnIndex.AutoIncrement = true;
            this.columnIndex.AllowDBNull = true;

            this.columnId = new DataColumn("Id", typeof(int), null, MappingType.Element);
            base.Columns.Add(this.columnId);
            this.columnId.AllowDBNull = true;

            this.columnEventType = new DataColumn("EventType", typeof(TraceEventType), null, MappingType.Element);
            base.Columns.Add(this.columnEventType);
            this.columnEventType.AllowDBNull = true;

            this.columnMessage = new DataColumn("Message", typeof(string), null, MappingType.Element);
            base.Columns.Add(this.columnMessage);
            this.columnMessage.AllowDBNull = true;

            this.columnDetail = new DataColumn("Detail", typeof(string), null, MappingType.Element);
            base.Columns.Add(this.columnDetail);
            this.columnDetail.AllowDBNull = true;

            this.columnDateTime = new DataColumn("DateTime", typeof(string), null, MappingType.Element);
            base.Columns.Add(this.columnDateTime);
            this.columnDateTime.AllowDBNull = true;

            this.columnTimestamp = new DataColumn("Timestamp", typeof(string), null, MappingType.Element);
            base.Columns.Add(this.columnTimestamp);
            this.columnTimestamp.AllowDBNull = true;

            this.columnProcessId = new DataColumn("ProcessId", typeof(string), null, MappingType.Element);
            base.Columns.Add(this.columnProcessId);
            this.columnProcessId.AllowDBNull = true;

            this.columnThreadId = new DataColumn("ThreadId", typeof(string), null, MappingType.Element);
            base.Columns.Add(this.columnThreadId);
            this.columnThreadId.AllowDBNull = true;

            this.columnSource = new DataColumn("Source", typeof(string), null, MappingType.Element);
            base.Columns.Add(this.columnSource);
            this.columnSource.AllowDBNull = true;

            this.columnCallstack = new DataColumn("Callstack", typeof(string), null, MappingType.Element);
            base.Columns.Add(this.columnCallstack);
            this.columnCallstack.AllowDBNull = true;

            this.columnRelatedActivityId = new DataColumn("RelatedActivityId", typeof(Guid), null, MappingType.Element);
            base.Columns.Add(this.columnRelatedActivityId);
            this.columnRelatedActivityId.AllowDBNull = true;

            this.columnLogicalOperations = new DataColumn("LogicalOperations", typeof(string), null, MappingType.Element);
            base.Columns.Add(this.columnLogicalOperations);
            this.columnLogicalOperations.AllowDBNull = true;

            this.CaseSensitive = true;
            this.Locale = new CultureInfo("ja-JP");
        }

        public DataColumn IndexColumn { get { return this.columnIndex; } }
        public DataColumn IdColumn { get { return this.columnId; } }
        public DataColumn EventTypeColumn { get { return this.columnEventType; } }
        public DataColumn MessageColumn { get { return this.columnMessage; } }
        public DataColumn DetailColumn { get { return this.columnDetail; } }
        public DataColumn DateTimeColumn { get { return this.columnDateTime; } }
        public DataColumn TimestampColumn { get { return this.columnTimestamp; } }
        public DataColumn ProcessIdColumn { get { return this.columnProcessId; } }
        public DataColumn ThreadIdColumn { get { return this.columnThreadId; } }
        public DataColumn SourceColumn { get { return this.columnSource; } }
        public DataColumn CallstackColumn { get { return this.columnCallstack; } }
        public DataColumn RelatedActivityIdColumn { get { return this.columnRelatedActivityId; } }
        public DataColumn LogicalOperationsColumn { get { return this.columnLogicalOperations; } }
        public TraceData this[int index] { get { return ((TraceData)(this.Rows[index])); } }

        [Browsable(false)]
        public int Count { get { return this.Rows.Count; } }

        public event TraceDataChangeEventHandler TraceDataChanging;
        public event TraceDataChangeEventHandler TraceDataChanged;
        public event TraceDataChangeEventHandler TraceDataDeleting;
        public event TraceDataChangeEventHandler TraceDataDeleted;

        public void AddTraceData(TraceData row)
        {
            this.Rows.Add(row);
        }

        public TraceData AddTraceData(int Id, TraceEventType EventType, string Message, string Detail, string DateTime, string Timestamp, string ProcessId, string ThreadId, string Source, string Callstack, System.Guid RelatedActivityId, string LogicalOperations)
        {
            TraceData rowTraceData = ((TraceData)(this.NewRow()));
            object[] columnValuesArray = new object[] { null, Id, EventType, Message, Detail, DateTime, Timestamp, ProcessId, ThreadId, Source, Callstack, RelatedActivityId, LogicalOperations };
            rowTraceData.ItemArray = columnValuesArray;
            this.Rows.Add(rowTraceData);
            return rowTraceData;
        }

        public TraceData NewTraceData()
        {
            return ((TraceData)(this.NewRow()));
        }

        public void RemoveTraceData(TraceData row)
        {
            this.Rows.Remove(row);
        }

        #region IEnumerable<TraceData> メンバー

        IEnumerator<TraceData> IEnumerable<TraceData>.GetEnumerator()
        {
            throw new NotImplementedException();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.Rows.GetEnumerator();
        }

        #endregion

        public override DataTable Clone()
        {
            TraceDataTable cln = ((TraceDataTable)(base.Clone()));
            cln.InitVars();
            return cln;
        }

        protected override DataRow NewRowFromBuilder(DataRowBuilder builder)
        {
            return new TraceData(builder);
        }

        protected override Type GetRowType()
        {
            return typeof(TraceData);
        }

        protected override void OnRowChanged(DataRowChangeEventArgs e)
        {
            base.OnRowChanged(e);
            if ((this.TraceDataChanged != null))
                this.TraceDataChanged(this, new TraceDataChangeEventArgs(((TraceData)(e.Row)), e.Action));
        }

        protected override void OnRowChanging(DataRowChangeEventArgs e)
        {
            base.OnRowChanging(e);
            if ((this.TraceDataChanging != null))
                this.TraceDataChanging(this, new TraceDataChangeEventArgs(((TraceData)(e.Row)), e.Action));
        }

        protected override void OnRowDeleted(DataRowChangeEventArgs e)
        {
            base.OnRowDeleted(e);
            if ((this.TraceDataDeleted != null))
                this.TraceDataDeleted(this, new TraceDataChangeEventArgs(((TraceData)(e.Row)), e.Action));
        }

        protected override void OnRowDeleting(DataRowChangeEventArgs e)
        {
            base.OnRowDeleting(e);
            if ((this.TraceDataDeleting != null))
                this.TraceDataDeleting(this, new TraceDataChangeEventArgs(((TraceData)(e.Row)), e.Action));
        }
    }

}
